package reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 反射机制访问私有成员(暴力反射)
 * 反射机制可破坏单例模式
 *
 * Class的方法:
 *      Method getMethod(String name,Class... cls)
 *      Method[] getMethods()
 *      上述两个方法仅能获取该类的公开方法(包括从超类继承的方法)
 *
 *      getDeclaredMethod()
 *      getDeclaredMethods()
 *      上述两个方法可以获取本类定义的方法(含有私有的，不含有继承的)
 */
public class GetPrivateMethodDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,
            InstantiationException, IllegalAccessException, InvocationTargetException {
        Class<?> c = Class.forName("reflect.Person");
        Object o = c.newInstance();
        Method method = c.getDeclaredMethod("hehe");
        method.setAccessible(true);     // 强行打开访问权限
        method.invoke(o);
        method.setAccessible(false);    // 对于私有成员，访问后关闭(必须)

        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        System.out.println(s1);
        System.out.println(s2);
        c = Class.forName("reflect.Singleton");
        Constructor<?> constructor = c.getDeclaredConstructor();    // 获取私有的无参构造器
        constructor.setAccessible(true);
        Singleton s3 = (Singleton) constructor.newInstance();
        constructor.setAccessible(false);
        System.out.println(s3);
        s3.show();
    }
}
